package com.the_ring.chapter08.widget;

import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class FloatWindow {

    private Context mContext;       // 声明一个上下文对象
    private WindowManager vm;       // 声明一个窗口管理器对象
    private static WindowManager.LayoutParams vmParams; // 悬浮窗的布局参数
    private View mContentView;      // 声明一个内容视图对象
    private float mScreenX, mScreenY;   // 触摸点在屏幕上的横纵坐标
    private float mLastX, mLastY;   // 上次触摸点的横纵坐标
    private float mDownX, mDownY;   // 按下点的横纵坐标
    private boolean isShowing = false;  // 是否正在显示

    public FloatWindow(Context context) {
//        super(context);
        // 从系统服务中获取窗口管理器，后续通过该管理添加悬浮窗
        vm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        if (vmParams == null) {
            vmParams = new WindowManager.LayoutParams();
        }
        this.mContext = context;
    }

    // 设置悬浮窗的内容布局
    public void setLayout(int layoutId) {
        // 从指定资源编号的布局文件中获取内容视图对象
        mContentView = LayoutInflater.from(mContext).inflate(layoutId, null);
        // 接管悬浮窗的触摸事件，使之既可随手势拖动又可处理点击动作
        mContentView.setOnTouchListener((v, event) -> {
            mScreenX = event.getRawX();
            mScreenY = event.getRawY();
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                // 手指按下
                mDownX = mScreenX;
                mDownY = mScreenY;
            } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
                // 移动
                updateViewPosition();   // 更新视图位置
            } else if (event.getAction() == MotionEvent.ACTION_UP) {
                // 手指松开
                updateViewPosition(); // 更新视图位置
                if (Math.abs(mScreenX - mDownX) < 3 && Math.abs(mScreenY - mDownY) < 3) {
                    if (mListener != null) {
                        // 响应悬浮窗的点击事件
                        mListener.onFloatClick(v);
                    }
                }
            }
            mLastX = mScreenX;
            mLastY = mScreenY;
            return true;
        });
    }

    // 更新悬浮窗的视图位置
    private void updateViewPosition() {
        // 此处不能直接转为整数类型，因为小数部分会被截掉，重复多次后就会造成偏移越来越大
        vmParams.x = Math.round(vmParams.x + mScreenX - mLastX);
        vmParams.y = Math.round(vmParams.y + mScreenY - mLastY);
        vm.updateViewLayout(mContentView, vmParams);
    }

    // 显示悬浮窗
    public void show(int gravity) {
        if (mContentView != null) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                // 注意 TYPE_SYSTEM_ALERT 从 Android 8.0 开始被舍弃
                vmParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
            } else {
                // 从 Android 8.0 开始悬浮窗要使用 TYPE_APPLICATION_OVERLAY
                vmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            }
            vmParams.format = PixelFormat.RGBX_8888;
            vmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
            vmParams.alpha = 1.0f;  // 完全不透明
            vmParams.gravity = gravity; // 指定悬浮窗对齐方式
            vmParams.x = 0;
            vmParams.y = 0;
            // 设置悬浮窗的宽度和高度为自适应
            vmParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
            vmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
            // 添加自定义的窗口布局，然后在屏幕上就能看到悬浮窗了
            vm.addView(mContentView, vmParams);
            isShowing = true;
        }
    }

    // 关闭悬浮窗
    public void close() {
        if (mContentView != null) {
            vm.removeView(mContentView);    // 移除自定义的窗口布局
            isShowing = false;
        }
    }

    private FloatClickListener mListener; // 声明一个悬浮窗的点击监听器对象

    // 设置悬浮窗的点击监听器
    public void setOnFloatListener(FloatClickListener mListener) {
        this.mListener = mListener;
    }

    // 定义一个悬浮窗的点击监听器接口，用于触发点击动作
    public interface FloatClickListener {
        void onFloatClick(View v);
    }
}
